﻿#Region "Imports"
Imports System.DirectoryServices
#End Region

Public Class IIsSite
    Implements IDisposable

#Region "Privates"

    Private _SiteEntry As DirectoryEntry
    Private _RootEntry As DirectoryEntry

#End Region

#Region "Constructors and Destructors"

    Public Sub New(ByVal SiteEntry As DirectoryEntry, ByVal RootEntry As DirectoryEntry)

        If SiteEntry.SchemaClassName = SiteSchemaClassName And RootEntry.SchemaClassName = VirtualDirectorySchemaClassName Then

            _SiteEntry = SiteEntry
            _SiteEntry.RefreshCache()

            _RootEntry = RootEntry
            _RootEntry.RefreshCache()

        Else

            If SiteEntry.SchemaClassName <> SiteSchemaClassName Then

                ConstructorEx(SiteSchemaClassName)

            End If

            If RootEntry.SchemaClassName <> VirtualDirectorySchemaClassName Then

                ConstructorEx(VirtualDirectorySchemaClassName)

            End If

        End If

    End Sub

    Protected Overrides Sub Finalize()

        If Not _RootEntry Is Nothing Then _RootEntry.Close()
        If Not _SiteEntry Is Nothing Then _SiteEntry.Close()

    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose

        If Not _RootEntry Is Nothing Then _RootEntry.Close()
        If Not _SiteEntry Is Nothing Then _SiteEntry.Close()

    End Sub

#End Region

#Region "Properties"

    Public ReadOnly Property Id() As String
        Get

            Return _SiteEntry.Name

        End Get
    End Property

    Public ReadOnly Property State() As SiteStates
        Get

            Return GetProperty("ServerState", _SiteEntry)

        End Get
    End Property

    Public Property AutoStart() As Boolean
        Get

            Return GetProperty("ServerAutoStart", _SiteEntry)

        End Get
        Set(ByVal value As Boolean)

            SetProperty("ServerAutoStart", value, _SiteEntry)

        End Set
    End Property

    Public Property Description() As String
        Get

            Return GetProperty("ServerComment", _SiteEntry)
        End Get
        Set(ByVal value As String)

            SetProperty("ServerComment", value, _SiteEntry)

        End Set
    End Property

    Public Property Bindings() As SiteBinding()
        Get

            Dim ObjectsA = GetPropertyA("ServerBindings", _SiteEntry)
            Dim BindingsA() As SiteBinding

            If ObjectsA.Length > 0 Then

                ReDim BindingsA(ObjectsA.Length - 1)

                For wsbI = 0 To ObjectsA.Length - 1

                    Dim wsbA = ObjectsA(wsbI).Split(":"c)

                    BindingsA(wsbI).IP = wsbA(0)
                    BindingsA(wsbI).Port = wsbA(1)
                    BindingsA(wsbI).HostHeader = wsbA(2)

                Next

                Return BindingsA

            Else

                Return New SiteBinding() {}

            End If

        End Get
        Set(ByVal value As SiteBinding())

            Dim ObjectsA() As Object

            If value.Length > 0 Then

                ReDim ObjectsA(value.Length - 1)

                For wsbI = 0 To value.Length - 1

                    ObjectsA(wsbI) = String.Format("{0}:{1}:{2}", value(wsbI).IP, value(wsbI).Port, value(wsbI).HostHeader)

                Next

            Else

                ObjectsA = New Object() {}

            End If

            SetPropertyA("ServerBindings", ObjectsA, _SiteEntry)

        End Set
    End Property

    Public Property Bindings(ByVal index As Integer) As SiteBinding
        Get

            Dim ObjectA = GetPropertyA("ServerBindings", _SiteEntry)(index)
            Dim BindingA As SiteBinding

            Dim wsbA = ObjectA.Split(":"c)

            BindingA.IP = wsbA(0)
            BindingA.Port = wsbA(1)
            BindingA.HostHeader = wsbA(2)

            Return BindingA

        End Get
        Set(ByVal value As SiteBinding)

            Dim ObjectsA = GetPropertyA("ServerBindings", _SiteEntry)

            ObjectsA(index) = String.Format("{0}:{1}:{2}", value.IP, value.Port, value.HostHeader)

            SetPropertyA("ServerBindings", ObjectsA, _SiteEntry)

        End Set
    End Property


    Public Property ApplicationPoolId() As String
        Get

            Return GetProperty("AppPoolId", _RootEntry)

        End Get
        Set(ByVal value As String)

            SetProperty("AppPoolId", value, _RootEntry)

        End Set
    End Property

    Public Property ApplicationName() As String
        Get

            Return GetProperty("AppFriendlyName", _RootEntry)

        End Get
        Set(ByVal value As String)

            SetProperty("AppFriendlyName", value, _RootEntry)

        End Set
    End Property

    Public Property ASPNETVersion() As ASPNETVersions
        Get

            Return GetScriptMaps(_RootEntry.Path)

        End Get
        Set(ByVal value As ASPNETVersions)

            SetScriptMaps(_RootEntry.Path, value)

        End Set
    End Property


    Public Property DirectoryBrowsing() As DirectoryBrowseFlags
        Get

            Return GetProperty("DirBrowseFlags", _RootEntry)

        End Get
        Set(ByVal value As DirectoryBrowseFlags)

            SetProperty("DirBrowseFlags", value, _RootEntry)

        End Set
    End Property

    Public Property DefaultDocuments() As String
        Get

            Return GetProperty("DefaultDoc", _RootEntry)

        End Get
        Set(ByVal value As String)

            SetProperty("DefaultDoc", value, _RootEntry)

        End Set
    End Property

    Public Property AccessPermissions() As AccessPermissionFlags
        Get

            Return GetProperty("AccessFlags", _RootEntry)

        End Get
        Set(ByVal value As AccessPermissionFlags)

            SetProperty("AccessFlags", value, _RootEntry)

        End Set
    End Property

    Public Property AuthenticationMethods() As AuthenticationFlags
        Get

            Return GetProperty("AuthFlags", _RootEntry)

        End Get
        Set(ByVal value As AuthenticationFlags)

            SetProperty("AuthFlags", value, _RootEntry)

        End Set
    End Property

    Public Property Path() As String
        Get

            Return GetProperty("Path", _RootEntry)

        End Get
        Set(ByVal value As String)

            SetProperty("Path", value, _RootEntry)

        End Set
    End Property


    Public ReadOnly Property Directories() As IIsDirectory()
        Get

            Dim Dirs() As IIsDirectory = {}

            Try

                Dim DirEntries = From de As DirectoryEntry In _RootEntry.Children _
                                 Where de.SchemaClassName = DirectorySchemaClassName _
                                 Select de

                For Each d In DirEntries

                    ReDim Preserve Dirs(Dirs.Length)
                    Dirs(Dirs.Length - 1) = New IIsDirectory(d)

                Next

            Catch ex As Exception

                GetPropertyEx("Directories", ex)

            End Try

            Return Dirs

        End Get
    End Property

    Public ReadOnly Property VirtualDirectories() As IIsVirtualDirectory()
        Get

            Dim VirtualDirs() As IIsVirtualDirectory = {}

            Try

                Dim VirtualDirEntries = From vde As DirectoryEntry In _RootEntry.Children _
                                        Where vde.SchemaClassName = VirtualDirectorySchemaClassName _
                                        Select vde

                For Each vd In VirtualDirEntries

                    ReDim Preserve VirtualDirs(VirtualDirs.Length)
                    VirtualDirs(VirtualDirs.Length - 1) = New IIsVirtualDirectory(vd)

                Next

            Catch ex As Exception

                GetPropertyEx("VirtualDirectories", ex)

            End Try

            Return VirtualDirs

        End Get
    End Property

    Public ReadOnly Property Files() As IIsFile()
        Get

            Dim Fs() As IIsFile = {}

            Try

                Dim FileEntries = From fe As DirectoryEntry In _RootEntry.Children _
                                  Where fe.SchemaClassName = FileSchemaClassName _
                                  Select fe

                For Each f In FileEntries

                    ReDim Preserve Fs(Fs.Length)
                    Fs(Fs.Length - 1) = New IIsFile(f)

                Next

            Catch ex As Exception

                GetPropertyEx("Files", ex)

            End Try

            Return Fs

        End Get
    End Property

#End Region

#Region "Public Functions and Methods"

    Public Sub StartSite(Optional ByVal WaitTillDone As Boolean = True)

        If WaitTillDone Then

            _SiteEntry.Invoke("Start", Nothing)

        Else

            SetProperty("ServerCommand", 1, _SiteEntry)

        End If

        _SiteEntry.RefreshCache()

    End Sub

    Public Sub StopSite(Optional ByVal WaitTillDone As Boolean = True)

        If WaitTillDone Then

            _SiteEntry.Invoke("Stop", Nothing)

        Else

            SetProperty("ServerCommand", 2, _SiteEntry)

        End If

        _SiteEntry.RefreshCache()

    End Sub

    Public Sub PauseSite(Optional ByVal WaitTillDone As Boolean = True)

        If WaitTillDone Then

            _SiteEntry.Invoke("Pause", Nothing)

        Else

            SetProperty("ServerCommand", 3, _SiteEntry)

        End If

        _SiteEntry.RefreshCache()

    End Sub

    Public Sub ContinueSite(Optional ByVal WaitTillDone As Boolean = True)

        If WaitTillDone Then

            _SiteEntry.Invoke("Continue", Nothing)

        Else

            SetProperty("ServerCommand", 4, _SiteEntry)

        End If

        _SiteEntry.RefreshCache()

    End Sub

    Public Function AddDirectory(ByVal Name As String) As IIsDirectory

        AddDirectory = Nothing

        Try

            Dim d As DirectoryEntry = _RootEntry.Invoke("Create", DirectorySchemaClassName, Name)

            d.CommitChanges()

            AddDirectory = New IIsDirectory(d)

            d.Close()

        Catch ex As Exception

            Throw New Exception(String.Format("An error occured while trying to add Directory '{0}'.", Name), ex)

        End Try

    End Function

    Public Function AddVirtualDirectory(ByVal Name As String, ByVal Path As String) As IIsVirtualDirectory

        AddVirtualDirectory = Nothing

        Try

            Dim vd As DirectoryEntry = _RootEntry.Invoke("Create", VirtualDirectorySchemaClassName, Name)

            vd.CommitChanges()

            AddVirtualDirectory = New IIsVirtualDirectory(vd)

            AddVirtualDirectory.Path = Path

            vd.Close()

        Catch ex As Exception

            Throw New Exception(String.Format("An error occured while trying to add Virtual Directory '{0}'.", Name), ex)

        End Try

    End Function

    Public Function AddFile(ByVal Name As String) As IIsFile

        AddFile = Nothing

        Try

            Dim f As DirectoryEntry = _RootEntry.Invoke("Create", FileSchemaClassName, Name)

            f.CommitChanges()

            AddFile = New IIsFile(f)

            f.Close()

        Catch ex As Exception

            Throw New Exception(String.Format("An error occured while trying to add File '{0}'.", Name), ex)

        End Try

    End Function

#End Region

End Class
